/*
 * DataObjectImpl.h
 *
 *  Created on: 2012-9-1
 *      Author: yangentao@gmail.com
 */

#ifndef DATAOBJECTIMPL_H_
#define DATAOBJECTIMPL_H_
#include <windows.h>
#include <ole2.h>
#include <Unknwn.h>
#include <assert.h>
#include "../util/util.h"
#include "../util/UnicodeConvert.h"

#include "GlobalMem.h"

using namespace std;

IDataObject* CreateDataObject(const char* str, int len);
IDataObject * CreateDataObject(FORMATETC *fmtetc, STGMEDIUM *stgmeds, UINT count);

class DataObjectImpl: public IDataObject {
private:
	volatile LONG refCount;

	FORMATETC *formats;
	STGMEDIUM *stgs;
	LONG length;
public:
	string dragText;
public:
	DataObjectImpl();
	//stgs.hGlobal will be free when refCount ==0, carefull!
	DataObjectImpl(FORMATETC * formats, STGMEDIUM *stgs, int count);
	virtual ~DataObjectImpl();
public:
	void ReleaseStgMediums();
public:
	ULONG __stdcall AddRef(void);
	ULONG __stdcall Release(void);
	HRESULT __stdcall QueryInterface(REFIID riid, PVOID *ppv);
public:
	HRESULT __stdcall GetData(FORMATETC *pFEIn, STGMEDIUM *pSTM);
	HRESULT __stdcall GetDataHere( FORMATETC *pformatetc, STGMEDIUM *pmedium);
	HRESULT __stdcall QueryGetData( FORMATETC *pFE);
	HRESULT __stdcall GetCanonicalFormatEtc( FORMATETC *formatIn, FORMATETC *formatOut);
	HRESULT __stdcall SetData( FORMATETC *pformatetc, STGMEDIUM *pmedium, BOOL fRelease);
	HRESULT __stdcall EnumFormatEtc( DWORD dwDirection, IEnumFORMATETC **ppEnum);
	HRESULT __stdcall DAdvise( FORMATETC *pformatetc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection);
	HRESULT __stdcall DUnadvise( DWORD dwConnection);
	HRESULT __stdcall EnumDAdvise( IEnumSTATDATA **ppenumAdvise);
private:
	int LookupFormatEtc(FORMATETC *format);
};
#endif /* DATAOBJECTIMPL_H_ */
